/* eslint-disable max-lines */
import _ from "lodash";
import service from "@service";
import { isFilter } from "./utils";
// import formatting from "./dataFormatting.js";
import { formatDate } from "@utils";
import { getTokenInfo } from "@utils/session";
const minWidth = 60;
const getClearedObject = data => {
    let temp = { ...(data || {}) };

    Object.keys(temp).forEach(key => {
        if (['null', 'undefined'].indexOf(typeof temp[key]) !== -1) {
            delete temp[key];
        }
    });

    return temp;
};

export default {
    components: {
        // "com-ocj-pager": comOcjPager
    },
    props: {
        busCode: [Object, String],
        // 分页控制
        pagination: {
            type: Boolean,
            default: true
        },
        issummary:{
            type: Boolean,
            default: false
        },
        // border
        border: {
            type: Boolean,
            default: false
        },
        // 接口
        services: {
            type: String | Function
        },
        exts: {
            type: Array,
            default: function () {
                return [];
            }
        },
        summaryKey:{
            type: Array,
            default: function () {
                return [];
            }

        },
        /**
         * 配置列数组
         *  [{
         *      label: '操作', 必填    列名称
         *      value: 'key1', 必填    数据中对应key
         *      width: '60',   非必填   单位px
         *      slot: 'slot1', 非必填  可选自定义插槽
         *      valueFun: function(row){},  非必填   重写函数，参数为当前行数据
         *      type: 'date|operate|render',  非必填   可选值： 'date' 'operate'
         *      format: 'yyyy-MM-DD H:mm'  非必填 type === date 时重写时间格式，可通过format自定义格式
         *      buttons: [{
         *              label: '详情',  // 按钮文字
         *              click: 'detailCallback', // 回掉函数， 参数为当前行数据
         *              conditionFun: function(row) {}  // return true|false  该按钮显示与否
         *          }]  非必填， type === 'operate' 时必填
         *  }]
         */
        tableColumn: {
            type: Array,
            default: function () {
                return [];
            }
        },
        importData: {
            type: Array // 使用外部tableData数据，
        },
        param: {
            type: Object,
            default: function () {
                return {};
            }
        },
        showEmptyImg: {
            type: Boolean,
            default: false
        },
        paramsHandle: {
            type: Function
        }, // 参数处理
        dataFormatHandle: {
            type: Function
        }, // 数据处理
        autoLoad: {
            type: Boolean,
            default: true
        },
        rowKey: {
            type: [Function, String]
        },
        offScreenSet: Object,
        tableTitle: String,
        // url: String,
        //pageSizes: Array,
        pageSizes:{
            type: Array,
            default:()=>{
                //return [100,1000]
            }
        },
        tableNoWrap: {
            type: Boolean,
            default: false
        },
        totalData: {
            type: Number,
            default: 0
        },
        filterHandle: Function,
        // 是否为单选，否则为多选
        isSingleSelect: {
            type: Boolean,
            default: false
        },

        dataType: {
            type: String,
            default: 'data', // 可选 params | data
        },
    },
    watch: {
        param(val) {
            this.queryParams = { ...val };
        },
        tableData(val, oldVal) {
            if (!val || val === oldVal) {
                return;
            }

            if (this.currentSelectSign) {
                let tableDom = this.$refs.refTable.$el;

                if (tableDom) {
                    let tbodyEl = tableDom.querySelector(".el-table__body tbody");

                    (oldVal || []).forEach(v => {
                        let vEl = tbodyEl.querySelector(`.currentCheckbox_${v[this.rowKey]}`);

                        vEl.classList.remove('checked');
                    });

                    tableDom.querySelector(".currentCheckbox_all").classList.remove('checked');
                }

                this.selectedMap = {};
                this.selectList = [];
            }

            if (this.offScreenEffect) {
                setTimeout(() => {
                    this.updateOffScreen();
                }, 500);
            }
        },
        selectList(val) {
            if (this.currentSelectSign) {
                let selectedMap = {};
                (val || []).forEach(v => {
                    selectedMap[v[this.rowKey]] = v;
                });
                this.selectedMap = selectedMap;
                this.$emit('selected-change', val);
            }
        },
        totalData(n) {
            this.total = n;
        },
        radioSelect(n) {
            this.$emit('radio-change', n);
        },
        importData() {
            this.radioSelect = null;
        },
    },
    computed: {
        permission() {
            return function (config, type) {
                return "";
                // if(!this.$log || !this.$route) {
                //     return true;
                // }

                // let tip = type === 'column' ? '列：' : '按钮：';
                // if(config["permission"]){
                //     this.$log(tip + config.label + "  权限编码:"+ config.permission);
                //     return config.permission;
                // }
                // if(config["key"]){
                //     const code = this.$route.name + '_' +config.key;
                //     this.$log(tip + config.label + "  权限编码:"+ code);
                //     return code;
                // }else if(config['value']) {
                //     const code = this.$route.name + '_' +config.value;
                //     this.$log(tip + config.label + "  权限编码:"+ code);
                //     return code;
                // }
                // if(config["click"]){
                //     const code = this.$route.name + '_' +config.click;
                //     this.$log(tip + config.label + "  权限编码:"+ code);
                //     return code;
                // }
                // return "";
            };
        },
        paginationInfo() {
            return {
                total: this.total,
                pager: this.pager,
                selected: this.selectList.length
            };
        },
        // 操作项留出宽度
        autoWith() {
            return function (options) {
                let width = minWidth;
                if (options && options.length > 0) {
                    width = options.length * 50;
                    return minWidth > width ? minWidth : width;
                }
                return 0;
            };
        },
        tableData() {
            let data = this.importData ? this.importData : this.dataSet;
            if (this.filterHandle) {
                data = data.filter(this.filterHandle);
            }
            return data;
        },
        // 功能控制 是否展示列
        computedShowColumn() {
            return (row) => {
                let permission = row.permission;
                if(typeof permission === 'boolean') {
                    return permission
                }else if(typeof permission === 'string') {
                    return this.$store.getters["account/getPermissionJudgeHandle"](permission)
                }
                return true;
            };
        },
        offScreenEffect() {
            return this.rowKey && this.offScreenSet && this.offScreenSet.heightPerLine;
        },
        selectSign() {
            return (this.tableColumn || []).filter(v => v.type === 'select').length;
        },
        currentSelectSign() {
            return (this.tableColumn || []).filter(v => v.type === 'select').length && this.offScreenEffect;
        },
        finalTableColumn() {
            if (!this.currentSelectSign) {
                return this.tableColumn;
            }

            let tempTableColumn = [...(this.tableColumn || [])];

            return tempTableColumn.map(v => {
                if (v.type === 'select') {
                    return {
                        value: v.value,
                        type: 'render',
                        render: (h, { data: { row } }) => {
                            let selectedMap = this.selectedMap || {};

                            return (
                                <div
                                    class={`currentCheckbox currentCheckbox_${row[this.rowKey]
                                        }${selectedMap[
                                            row[this.rowKey]
                                        ]
                                            ? " checked"
                                            : ""
                                        }`}
                                    on-click={
                                        (e) => {
                                            e.stopPropagation();
                                            this.currentSelectHandle(row);
                                        }
                                    }
                                />
                            );
                        },
                        headerRender: (h) => {
                            return <div class="currentCheckbox currentCheckbox_all" on-click={() => this.currentSelectAllHandle()}></div>;
                        }
                    };
                }
                return v;
            });
        },
    },
    data() {
        return {
            queryParams: null,
            loading: false,
            total: this.totalData || 0, // 总数据量
            pager: {
                pageNo: 1,
                pageSize: this.pageSizes ? this.pageSizes[0] : 10
            },
            dataSet: [],
            selectList: [],
            radioSelect: null,
            speciaVal: {},
            lastQueryParams: null,
            onShiftPress: false
        };
    },
    created() {
        if (this.autoLoad) {
            this.onQuery();
        }
    },
    activated() {
        this.bindEvent();
    },
    deactivated() {
        this.unbindEvent();
    },
    destroyed() {
        this.unbindEvent();
    },
    mounted() {
        this.bindEvent();
    },
    methods: {
         // 对外暴露方法
         $getSelected() {
            return this.selectList;
        },
        bindEvent() {
            this.unbindEvent();
            document.documentElement.addEventListener('keydown', this.keydown);
            document.documentElement.addEventListener('keyup', this.keyup);
        },
        unbindEvent() {
            document.documentElement.removeEventListener('keydown', this.keydown);
            document.documentElement.removeEventListener('keyup', this.keyup);
        },
        keydown(e) {
            if (e.keyCode === 16) {
                this.onShiftPress = true;
            }
        },
        keyup(e) {
            if (e.keyCode === 16) {
                this.onShiftPress = false;
            }
        },
        currentSelectAllHandle() {
            let tableDom = this.$refs.refTable.$el;
            let vEl = tableDom.querySelector(".currentCheckbox_all");

            if (this.selectList.length === this.tableData.length) {
                this.updateCurrentSelect(this.tableData.map(v => ({
                    row: v,
                    check: false,
                    id: v[this.rowKey]
                })));

                vEl.classList.remove('checked');
            } else {
                this.updateCurrentSelect(this.tableData.map(v => ({
                    row: v,
                    check: true,
                    id: v[this.rowKey]
                })));

                vEl.classList.add('checked');
            }
        },
        currentSelectHandle(row) {
            let selectedMap = this.selectedMap || {};

            let toCheck = !selectedMap[row[this.rowKey]];

            let { selection } = this.updateCurrentSelect([{ check: toCheck, id: row[this.rowKey], row }]);

            this.selectHandle(selection, row);
        },
        updateCurrentSelect(changeList) {
            let tableDom = this.$refs.refTable.$el;

            let tbodyEl = tableDom.querySelector(".el-table__body tbody");

            let selection = [...this.selectList];

            changeList.forEach(v => {
                let vClassName = `currentCheckbox_${v.id}`;

                let vEl = tbodyEl.querySelector(`.${vClassName}`);

                let tempIndex = selection.indexOf(v.row);

                if (v.check) {
                    vEl.classList.add('checked');

                    if (tempIndex === -1) {
                        selection.push(v.row);
                    }
                } else {
                    vEl.classList.remove('checked');

                    if (tempIndex !== -1) {
                        selection.splice(tempIndex, 1);
                    }
                }
            });

            this.selectionChange(selection, { innerHandle: true });

            return {
                selection
            };
        },
        updateOffScreen() {
            if (!this.offScreenEffect) {
                return;
            }

            let tableDom = this.$refs.refTable.$el;

            let tbodyEl = tableDom.querySelector(".el-table__body tbody");

            let scrollState = tbodyEl.getBoundingClientRect();

            let heightPerLine = this.offScreenSet.heightPerLine;

            let onViewSet = {
                yStart: -scrollState.top,
                yEnd: (window.innerHeight || document.documentElement.clientHeight) - scrollState.top
            };

            let cacheRenderCount = 5;

            let rowIndexStart = Math.floor(onViewSet.yStart / heightPerLine) - cacheRenderCount;
            let rowIndexEnd = Math.ceil(onViewSet.yEnd / heightPerLine) + cacheRenderCount;

            if (rowIndexStart < 0) {
                rowIndexStart = 0;
            }

            if (rowIndexEnd > this.tableData.length - 1) {
                rowIndexEnd = this.tableData.length - 1;
            }

            let rowElList = tbodyEl.querySelectorAll('.el-table__row');
            // let rowElListOldView = tbodyEl.querySelectorAll('.el-table__row.view');

            // for (let i = 0; i < rowElListOldView.length; i++) {
            //     rowElListOldView[i].className = rowElListOldView[i].className.replace(' view', '');
            // }

            // for (let i = rowIndexStart; i <= rowIndexEnd; i++) {
            //     if(rowElList[i]){
            //         rowElList[i].className = rowElList[i].className += ' view';
            //     }
            // }

            Array.prototype.forEach.call(rowElList, (rowEl, index) => {
                if (index >= rowIndexStart && index <= rowIndexEnd) {
                    rowEl.style.display = 'table-row';
                } else {
                    rowEl.style.display = 'none';
                }
                rowEl.style.minHeight = `${heightPerLine}px`;
                rowEl.style.maxHeight = `${heightPerLine}px`;
            });

            let topPaddingEl = tableDom.querySelector(".top-padding");
            let bottomPaddingEl = tableDom.querySelector(".bottom-padding");

            if (!topPaddingEl) {
                let trEl = document.createElement('tr');
                trEl.className = "top-padding";
                tbodyEl.insertBefore(trEl, rowElList[0]);
                topPaddingEl = trEl;
            }

            if (!bottomPaddingEl) {
                let trEl = document.createElement('tr');
                trEl.className = "bottom-padding";
                tbodyEl.appendChild(trEl);
                bottomPaddingEl = trEl;
            }

            topPaddingEl.style.height = `${rowIndexStart * heightPerLine}px`;
            bottomPaddingEl.style.height = `${((rowElList.length || 1) - rowIndexEnd - 1) * heightPerLine}px`;
        },
        async selectHandle(selection, row) {
            let tempSelection = [...selection];
            if (this.rowKey && this.onShiftPress) {
                await new Promise(resolve => this.$nextTick(resolve));

                let selectedMap = {};
                if (!selection || selection.length < 1) {
                    return;
                }
                selection.forEach(v => {
                    selectedMap[v[this.rowKey]] = v;
                });
                if (!selectedMap[row[this.rowKey]]) {
                    return;
                }

                let tableDataIndexMap = {};
                this.tableData.forEach((v, i) => {
                    tableDataIndexMap[v[this.rowKey]] = {
                        index: i,
                        item: v
                    };
                });

                let rowIndex =
                    tableDataIndexMap[row[this.rowKey]].index;
                let nearestIndex = 0;
                let currentRow = _.get(this.$refs, "refTable.store.states.currentRow");
                for (let i = 0; i < this.tableData.length; i++) {
                    if (currentRow === this.tableData[i]) {
                        nearestIndex = i;
                        break;
                    }
                }
                // null;
                // selection.forEach(v => {
                //     let tempIndex =
                //         tableDataIndexMap[v[this.rowKey]].index;
                //     if (tempIndex === rowIndex) {
                //         return;
                //     }
                //     if (
                //         nearestIndex === null ||
                //         Math.abs(nearestIndex - rowIndex) >
                //             Math.abs(tempIndex - rowIndex)
                //     ) {
                //         nearestIndex = tempIndex;
                //     }
                // });
                let needToSelect = [];
                let step = nearestIndex > rowIndex ? 1 : -1;
                let i = 0;
                for (
                    i = rowIndex + step;
                    i !== nearestIndex &&
                    i >= 0 &&
                    i < this.tableData.length;
                    i += step
                ) {
                    if (!selectedMap[this.tableData[i][this.rowKey]]) {
                        needToSelect.push(this.tableData[i]);
                    }
                }
                if (i === nearestIndex && !selectedMap[this.tableData[nearestIndex][this.rowKey]]) {
                    needToSelect.push(currentRow);
                }

                if (needToSelect.length) {
                    if (this.currentSelectSign) {
                        this.updateCurrentSelect(needToSelect.map(v => ({
                            id: v[this.rowKey],
                            check: true,
                            row: v
                        })));
                    } else {
                        needToSelect.forEach(v => {
                            this.$refs.refTable.toggleRowSelection(
                                v,
                                true
                            );
                        });
                    }

                    this.selectionChange([...selection, ...needToSelect], { innerHandle: true });

                    return;
                }
            } else if (this.selectSign && this.isSingleSelect) {
                (selection || []).forEach(item => {
                    if (item !== row) {
                        this.$refs.refTable.toggleRowSelection(item, false);
                    }
                })
                tempSelection = [row];
            }
            this.selectionChange(tempSelection, { innerHandle: true });
            this.$emit('on-select',selection, row)
        },
        // 清空表格项选择
        clearSelection() {
            let ref = this.$refs.refTable;
            ref && ref.clearSelection();
            this.selectionChange([], { innerHandle: true });
        },
        /**
         * @method 操作项按钮点击处理函数
         * @param {String} event
         * @param {Object} rowData
         */
        callBack(event, rowData) {
            event && this.$emit(event, rowData);
        },
        /**
         * @method 多选触发事件
         * @param {Array} selectList
         */
        selectionChange(selectList, { innerHandle } = {}) {
           
            this.selectList = selectList;
            if ((innerHandle && this.currentSelectSign) || !innerHandle) {
                this.$emit("selected-change", this.selectList);
            }
        },
        currentChange(row) {
            this.radioSelect = row
        //业务组件中独立处理事件
        // if ((innerHandle && this.currentSelectSign) || !innerHandle) {
        //     this.$emit("selected-change", this.selectList);
        // }
        },
        getSummaries(param){ //新增合计
           
            const { columns, data } = param;
            const sums = [];
            columns.forEach((column, index) => {
              if (index === 0) {
                sums[index] = '小计（元）';
                return;
              }
              let keys=''
              if(this.tableColumn[index].issummary){
                 keys=this.tableColumn[index].value
              }  
              const values = data.map(item => Number(item[column.property]));
              if (column.property === keys) {
              
                sums[index] = values.reduce((prev, curr) => {
                  const value = Number(curr);
                  if (!isNaN(value)) {
                    return prev + curr;
                  } else {
                    return prev;
                  }
                }, 0);
                //sums[index] += 0;
              }else{
                sums[index] = '--'
              }
                
              if(typeof(sums[index])!='string'){
                sums[index]=sums[index].toFixed(2)
              }
            });
            return sums;
        },
        selectAll(selection) {
            this.$emit('select-all', selection);
            if (this.isSingleSelect && selection.length > 1) {
                this.clearSelection();
            } else {
                this.selectionChange(selection, { innerHandle: true });
            }
        },
        /**
         * @method 分页变化
         * @param {Object} data
         */
        $comSelectChange(data) {
            this.pager = Object.assign(this.pager, data);
            this.onQuery({ pageChange: true });
            this.$emit('pageChange', this.pager);
        },
        /**
         * @method 按钮显示条件
         */
        btnCondition(btn, scope) {
            if (btn.conditionFun) {
                return btn.conditionFun.call(this, scope.row);
            }
            return true;
        },
        /**
         * @method 格式化表格数据
         */
        formatFun(data, row) {
            const column = isFilter(this.tableColumn, item => {
                return item.value === row.property;
            });
            if (column["valueFun"]) {
                return column.valueFun.call(this, data);
            }
            if (column["rewrite"]) {
                return column.rewrite[data[row.property]];
            }
            if (column["type"] === "date") {
                let format = column["format"];
                return formatDate(
                    new Date(data[row.property]),
                    format || "yyyy-MM-DD H:mm"
                );
            }
            return data[row.property];
        },
        /**
         * @returns {Object}
         */
        getParam() {
            let params = Object.assign(this.queryParams || {}, getClearedObject(this.param || {}), {
                ...(this.pagination ? { 
                    page: this.pager,
                    pageNum: this.pager?.pageNo,
                    pageSize: this.pager?.pageSize
                } : {})
            });
            if (this.paramsHandle) {
                return this.paramsHandle(params);
            }
            // Object.keys(params).forEach(key=>{
            //     // 空字符串,null,undefined不传
            //     if(!params[key] && params[key] !== 0){
            //         delete params[key];
            //     }
            // });
            return params;
        },
        /**
         * @method 获取数据
         */
        onQuery({ pageChange = false } = {}) {
            return this.request({ pageChange: true });
        },
        setParam(param) {
            this.queryParams = param;
        },
        clearParam() {
            this.queryParams = {};
        },
        setPagerNumber(pagerNumber, pagerSize) {

            let pager = { pageNo: pagerNumber };
            if(pagerSize) {
                pager.pageSize = pagerSize;
            }
            this.pager = Object.assign({}, this.pager, pager);
        },
        getSelectList() {
            return this.selectList;
        },
        getFullData() {
            return {
                total: this.total,
                pager: this.pager,
                dataSet: this.dataSet,
                selectList: this.selectList,
                lastQueryParams: this.lastQueryParams
            };
        },
        /**
         * @method 获取table数据
         */
        async request({ pageChange = false } = {}) {
            if (!this.services) {
                return;
            }
            if (!pageChange) {
                this.setPagerNumber(1);
            }
            this.loading = true;
            this.dataSet = []
            // const url = this.url || window.g_apiGet(this.services),
            const serviceName = this.services,
                params = this.getParam();
            const tokenInfo = getTokenInfo() || {};
            let list = []
            // let result = await service(serviceName, {
            //     // method: 'post',
            //     [this.dataType]: params,
            //     busCode: this.busCode,
            //     // params: params,
            //     noMessageTip: true,
            //     timeout:60000,
            // }).catch(err => {
            //     this.loading = false;
            //     throw err;
            // })
            let result = await this.services(params).catch(err => {
                this.loading = false;
                throw err;
            })
            this.lastQueryParams = params;
            this.loading = false;
            this.radioSelect = null;

            if (this.dataFormatHandle) {
                result = this.dataFormatHandle(result,serviceName);
            } //表格数据格式化
            if (result && Array.isArray(result)) {
                this.dataSet = result || [];
                this.total = result.length || 0;
            } else {
                this.dataSet = (result && result["list"]) || [];
                this.total = (result && result["total"]) || 0;
            }
            // 默认选中第一行
            if (
                this.dataSet &&
                Array.isArray(this.dataSet) &&
                this.dataSet.length
            ) {
                let ref = this.$refs.refTable;
                ref && ref.setCurrentRow(this.dataSet[0]);
            }
            //处理表格数据
            this.$emit("data-change", this.getFullData());

            setTimeout(() => {
                if (this.$refs.refTable&&this.$refs.refTable.doLayout){
                    this.$refs.refTable.doLayout()
                }else {
                    console.log('this.$refs.refTable.doLayout===',undefined);
                }

            }, 1000);
        },
        setCurrentRow(row) {
            let ref = this.$refs.refTable;
            ref && ref.setCurrentRow(row);
        },
        sortChange() {
            this.$nextTick(() => {
                this.updateOffScreen();
            });
        },
        filterChange() {
            this.$nextTick(() => {
                this.updateOffScreen();
            });
        },
        setCurrentRadio(row) {
            this.radioSelect = row
        }
    }
};
